﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
using System.Collections;
using System.Web.UI.WebControls;
using System.Security.Cryptography;

/// <summary>
/// Summary description for Utils
/// </summary>
public class Utils
{
    /// <summary>
    /// Joins a array using a separator.
    /// </summary>
    /// <param name="array">The array to join.</param>
    /// <param name="separator">The separator to use.</param>
    /// <param name="trim">If set to <c>true</c>, trims whitespace from each index.</param>
    /// <returns></returns>
    public static string Implode(string[] array, string separator, bool trim) {
        StringBuilder buffer = new StringBuilder();
        int num = array.Length;
        for(int i = 0; i < num; i++) {
            if(trim) {
                buffer.Append(array[i].Trim());
            } else {
                buffer.Append(array[i]);
            }
            if(i + 1 < num) {
                buffer.Append(separator);
            }
        }
        return buffer.ToString();
    }

    /// <summary>
    /// Joins a list using a separator.
    /// </summary>
    /// <param name="list">The list to join.</param>
    /// <param name="separator">The separator to use.</param>
    /// <param name="trim">If set to <c>true</c>, trims whitespace from each index.</param>
    /// <returns></returns>
    public static string Implode(List<string> list, string separator, bool trim) {
        StringBuilder buffer = new StringBuilder();
        int num = list.Count;
        for(int i = 0; i < num; i++) {
            if(trim) {
                buffer.Append(list[i].Trim());
            } else {
                buffer.Append(list[i]);
            }
            if(i + 1 < num) {
                buffer.Append(separator);
            }
        }
        return buffer.ToString();
    }

    /// <summary>
    /// Generates a (hopefully) unique ID using a combination of 53 (non-HTML safe) or 39 (HTML safe) characters.
    /// There are 1.74e17 combinations if the ID does not need to be HTML safe, otherwise there are just over 3500 million
    /// </summary>
    /// <param name="HTMLSafe"><c>true</c> if the generated ID must be valid in HTML without encoding.</param>
    /// <returns>The generated ID</returns>
    public static string GenID(bool HTMLSafe) {
        StringBuilder bld = new StringBuilder();
        int len = 6;
        Random seed = new Random();
        if(HTMLSafe) {
            string possible = "ABCEDFGHIJKLMNOPQRSTUVWXYZ0123456789~_-",
                   firstPossible = "ABCEDFGHIJKLMNOPQRSTUVWXYZ"; // make sure the first character isn't a number, which invalidates xhtml
            bld.Append(possible[seed.Next(firstPossible.Length - 1)]);
            for(int i = 1; i < len; i++) {
                bld.Append(possible[seed.Next(possible.Length - 1)]);
            }
        } else {
            string possible = "ABCEDFGHIJKLMNOPQRSTUVWXYZ0123456789%£$!*/#~][{}|=_-^";
            for(int i = 0; i < len; i++) {
                bld.Append(possible[seed.Next(possible.Length - 1)]);
            }
        }
        return bld.ToString();
    }

    /// <summary>
    /// Calculates the MD5 hash of the specified text
    /// </summary>
    /// <param name="text">The text.</param>
    /// <returns>The MD5 hash.</returns>
    public static string MD5(string text) {
        MD5 md5 = new MD5CryptoServiceProvider();
        byte[] originalBytes = ASCIIEncoding.UTF8.GetBytes(text);
        byte[] encodedBytes = md5.ComputeHash(originalBytes);
        return BitConverter.ToString(encodedBytes).Replace("-", "").ToLower();
    }

    /// <summary>
    /// Applies salt to a password.
    /// </summary>
    /// <param name="password">The password.</param>
    /// <returns></returns>
    public static string SaltPassword(string password) {
        return SaltPassword(password, System.Web.Configuration.WebConfigurationManager.AppSettings["salt"]);
    }
    /// <summary>
    /// Applies salt to a password.
    /// </summary>
    /// <param name="password">The password.</param>
    /// <param name="salt">The salt to use.</param>
    /// <returns></returns>
    public static string SaltPassword(string password, string salt) {
        return MD5(salt + password);
    }

    public static string HtmlEncode(string text) {
        char[] chars = HttpUtility.HtmlEncode(text).ToCharArray();
        StringBuilder result = new StringBuilder((int)(text.Length * 1.1));
        foreach(char c in chars) {
            int value = Convert.ToInt32(c);
            if(value > 127) {
                result.AppendFormat("&#{0};", value);
            } else {
                result.Append(c);
            }
        }
        return result.ToString();
    }

    public static string HtmlDecode(string text) {
        char[] chars = HttpUtility.HtmlDecode(text).ToCharArray();
        return new string(chars);
    }

    /// <summary>
    /// Converts a .NET compatible country code to a Java compatible country code. These are mostly the same apart from a couple of unique cases.
    /// </summary>
    /// <param name="dotNetCulture">The dot net culture.</param>
    /// <returns></returns>
    public static string DotNetCulture2JavaCulture(string dotNetCulture) {
        string javaCulture = string.Empty;
        switch(dotNetCulture) {
            case "he-IL":
                javaCulture = "iw_IL"; // bug as of Java v1.6.7
                break;
            case "zh-Hans":
                javaCulture = "zh_CN";
                break;
            case "zh-Hant":
                javaCulture = "zh_TW";
                break;
            default:
                javaCulture = dotNetCulture.Replace('-', '_');
                break;
        }
        return javaCulture;
    }

    /// <summary>
    /// Converts a Java compatible country code to a .NET compatible country code. These are mostly the same apart from a couple of unique cases.
    /// </summary>
    /// <param name="dotNetCulture">The dot net culture.</param>
    /// <returns></returns>
    public static string JavaCulture2DotNetCulture(string javaCulture) {
        string dotNetCulture = string.Empty;
        switch(javaCulture) {
            case "iw_IL":
                dotNetCulture = "he-IL"; // bug as of Java v1.6.7
                break;
            default:
                dotNetCulture = javaCulture.Replace('_', '-');
                break;
        }
        return dotNetCulture;
    }
}
